<template>
  <div class="whitelist-management">
    <!-- 筛选表单 -->
    <el-card class="filter-card" :body-style="{ padding: '15px' }">
      <DynamicForm
        ref="formRef"
        v-model="formData"
        :form-config="formConfig"
        :gutter="16"
        label-width="100px"
        type="search"
        @search="handleSearch"
        @reset="handleReset"
      />
    </el-card>

    <!-- 数据表格 -->
    <el-card class="table-card" :body-style="{ padding: '15px' }">
      <DynamicTable
        ref="tableRef"
        :data="tableData"
        :columns="columns"
        :loading="loading"
        :pagination="pagination"
        :selection-type="'multiple'"
        row-key="id"
        border
        @selection-change="handleSelectionChange"
        @size-change="handleSizeChange"
        @current-page-change="handlePageChange"
      >
        <template #table-top>
          <el-button type="primary" @click="handleCreate"> 新增规则 </el-button>
          <el-button type="default" @click="fetchList" :loading="loading">
            刷新
          </el-button>
        </template>
        <template #status="{ row }">
          <el-switch
            v-model="row.is_enabled"
            :active-value="true"
            :inactive-value="false"
            @change="handleStatusChange(row)"
            :loading="row._switching"
          />
        </template>
        <template #action="{ row }">
          <el-button size="small" @click="handleEdit(row)">编辑</el-button>
          <el-button size="small" type="danger" @click="handleDelete(row)">
            删除
          </el-button>
        </template>
      </DynamicTable>
    </el-card>

    <!-- 创建/编辑对话框 -->
    <el-dialog
      v-model="showDialog"
      :title="isEdit ? '编辑规则' : '新增规则'"
      width="800px"
      destroy-on-close
      @close="handleCloseDialog"
    >
      <DynamicForm
        ref="ruleFormRef"
        v-model="ruleFormData"
        :form-config="ruleFormConfig"
        label-width="120px"
        type="submit"
        @submit="handleSave"
        @cancel="handleCloseDialog"
      />
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, computed, onMounted, watch } from "vue";
import { ElMessage, ElMessageBox } from "element-plus";
import DynamicForm from "@/components/DynamicForm/index.vue";
import DynamicTable from "@/components/DynamicTable/index.vue";
import type { DynamicFormInstance } from "@/components/DynamicForm/types";
import type { DynamicTableInstance } from "@/components/DynamicTable/types";
import type { FormItemConfig } from "@/components/DynamicForm/types";
import type {
  TableColumn,
  PaginationConfig,
} from "@/components/DynamicTable/types";
import {
  getWhitelistRuleList,
  createWhitelistRule,
  updateWhitelistRule,
  deleteWhitelistRule,
} from "../../../servers";
import { getDimensionList } from "../../../servers";

// 表格引用
const formRef = ref<DynamicFormInstance>();
const tableRef = ref<DynamicTableInstance>();
const ruleFormRef = ref<DynamicFormInstance>();

// 状态
const loading = ref(false);
const showDialog = ref(false);
const isEdit = ref(false);
const currentRuleId = ref<number | null>(null);

// 表格数据
const tableData = ref<any[]>([]);
const selectedRows = ref<any[]>([]);

// 分页配置
const pagination = reactive<PaginationConfig>({
  currentPage: 1,
  pageSize: 20,
  total: 0,
  pageSizes: [10, 20, 50, 100],
  layout: "total, sizes, prev, pager, next, jumper",
  background: true,
});

// 筛选表单数据
const formData = reactive({
  rule_type: "",
  is_enabled: "",
  keyword: "",
});

// 规则表单数据
const ruleFormData = reactive({
  rule_name: "",
  rule_type: "ip_range",
  rule_description: "",
  match_condition_field: "asset_ip",
  match_condition_operator: "in_range",
  match_condition_value: "",
  match_condition_start_ip: "",
  match_condition_end_ip: "",
  match_condition_cidr: "",
  applicable_dimensions: [] as string[],
  effective_time_type: "permanent",
  effective_start: "",
  effective_end: "",
  is_enabled: true,
});

// 维度列表
const dimensionList = ref<any[]>([]);

// 筛选表单配置
const formConfig: FormItemConfig[] = [
  {
    key: "rule_type",
    name: "规则类型",
    type: "select",
    placeholder: "选择规则类型",
    params: {
      clearable: true,
    },
    options: [
      { label: "全部", value: "" },
      { label: "IP地址", value: "ip" },
      { label: "IP段", value: "ip_range" },
      { label: "端口", value: "port" },
      { label: "CVE", value: "cve" },
      { label: "维度", value: "dimension" },
      { label: "自定义", value: "custom" },
    ],
    col: { span: 6 },
  },
  {
    key: "is_enabled",
    name: "启用状态",
    type: "select",
    placeholder: "选择状态",
    params: {
      clearable: true,
    },
    options: [
      { label: "全部", value: "" },
      { label: "启用", value: "true" },
      { label: "禁用", value: "false" },
    ],
    col: { span: 6 },
  },
  {
    key: "keyword",
    name: "关键词",
    type: "input",
    placeholder: "搜索规则名称和描述",
    params: {
      clearable: true,
    },
    col: { span: 6 },
  },
];

// 获取维度列表
const fetchDimensionList = async () => {
  try {
    // 获取所有维度列表用于选择
    const response = await getDimensionList({ page_size: 100 });
    const data = response.data?.data || response.data;
    const dimensions = data?.dimensions || data?.items || [];
    dimensionList.value = dimensions.map((d: any) => ({
      label: d.dimension_name || d.dimension_code,
      value: d.dimension_code,
    }));
  } catch (error) {
    console.error("获取维度列表失败:", error);
  }
};

// 规则表单配置（动态生成）
const ruleFormConfig = computed<FormItemConfig[]>(() => {
  const configs: FormItemConfig[] = [
    {
      key: "rule_name",
      name: "规则名称",
      type: "input",
      placeholder: "请输入规则名称",
      rules: [{ required: true, message: "请输入规则名称", trigger: "blur" }],
    },
    {
      key: "rule_type",
      name: "规则类型",
      type: "radio",
      params: {
        options: [
          { label: "IP地址", value: "ip" },
          { label: "IP段", value: "ip_range" },
          { label: "端口", value: "port" },
          { label: "CVE", value: "cve" },
          { label: "维度", value: "dimension" },
          { label: "自定义", value: "custom" },
        ],
      },
      rules: [{ required: true, message: "请选择规则类型", trigger: "change" }],
    },
  ];

  // 根据规则类型显示不同的匹配条件输入
  if (ruleFormData.rule_type === "ip_range") {
    // IP段类型：支持CIDR或起始IP-结束IP
    configs.push({
      key: "match_condition_cidr",
      name: "CIDR",
      type: "input",
      placeholder: "例如: 10.0.1.0/24",
      show: () => ruleFormData.rule_type === "ip_range",
    });
    configs.push({
      key: "match_condition_start_ip",
      name: "起始IP",
      type: "input",
      placeholder: "例如: 10.0.1.0（不填写CIDR时使用）",
      show: () =>
        ruleFormData.rule_type === "ip_range" &&
        !ruleFormData.match_condition_cidr,
    });
    configs.push({
      key: "match_condition_end_ip",
      name: "结束IP",
      type: "input",
      placeholder: "例如: 10.0.1.255（不填写CIDR时使用）",
      show: () =>
        ruleFormData.rule_type === "ip_range" &&
        !ruleFormData.match_condition_cidr,
    });
  } else if (ruleFormData.rule_type === "ip") {
    configs.push({
      key: "match_condition_value",
      name: "IP地址",
      type: "input",
      placeholder: "例如: 192.168.1.100",
      rules: [{ required: true, message: "请输入IP地址", trigger: "blur" }],
    });
  } else if (ruleFormData.rule_type === "port") {
    configs.push({
      key: "match_condition_value",
      name: "端口号",
      type: "input",
      placeholder: "例如: 8080,8888（多个端口用逗号分隔）",
      rules: [{ required: true, message: "请输入端口号", trigger: "blur" }],
    });
  } else if (ruleFormData.rule_type === "cve") {
    configs.push({
      key: "match_condition_value",
      name: "CVE编号",
      type: "input",
      placeholder: "例如: CVE-2023-12345",
      rules: [{ required: true, message: "请输入CVE编号", trigger: "blur" }],
    });
  } else {
    configs.push({
      key: "match_condition_value",
      name: "匹配值",
      type: "input",
      placeholder: "请输入匹配值",
      rules: [{ required: true, message: "请输入匹配值", trigger: "blur" }],
    });
  }

  configs.push(
    {
      key: "applicable_dimensions",
      name: "适用维度",
      type: "select",
      placeholder: "选择适用维度（可多选）",
      params: {
        multiple: true,
        clearable: true,
      },
      options: [{ label: "全部", value: "*" }, ...dimensionList.value],
    },
    {
      key: "effective_time_type",
      name: "生效时间",
      type: "radio",
      params: {
        options: [
          { label: "永久生效", value: "permanent" },
          { label: "指定时间段", value: "time_range" },
        ],
      },
    },
    {
      key: "effective_start",
      name: "生效开始时间",
      type: "datetime",
      placeholder: "选择开始时间",
      params: {
        format: "YYYY-MM-DD HH:mm:ss",
        valueFormat: "YYYY-MM-DD HH:mm:ss",
      },
      show: () => ruleFormData.effective_time_type === "time_range",
    },
    {
      key: "effective_end",
      name: "生效结束时间",
      type: "datetime",
      placeholder: "选择结束时间",
      params: {
        format: "YYYY-MM-DD HH:mm:ss",
        valueFormat: "YYYY-MM-DD HH:mm:ss",
      },
      show: () => ruleFormData.effective_time_type === "time_range",
    },
    {
      key: "rule_description",
      name: "规则说明",
      type: "textarea",
      placeholder: "请输入规则说明",
      params: {
        rows: 3,
      },
    },
    {
      key: "is_enabled",
      name: "是否启用",
      type: "switch",
      params: {
        activeText: "启用",
        inactiveText: "禁用",
      },
    }
  );

  return configs;
});

// 表格列配置
const columns: TableColumn[] = [
  {
    label: "序号",
    prop: "serialNumber",
    width: 80,
    align: "center",
    formatter: (row: any, column: any, cellValue: any, index: number) => {
      return String(
        (pagination.currentPage - 1) * pagination.pageSize + index + 1
      );
    },
  },
  {
    label: "规则名称",
    prop: "rule_name",
    minWidth: 150,
    showOverflowTooltip: true,
  },
  {
    label: "规则类型",
    prop: "rule_type",
    minWidth: 100,
    align: "center",
    formatter: (row: any) => getRuleTypeName(row.rule_type),
  },
  {
    label: "范围/匹配值",
    prop: "match_condition_display",
    minWidth: 200,
    formatter: (row: any) => {
      if (row.match_condition) {
        if (row.match_condition.value) {
          return String(row.match_condition.value);
        }
        if (row.match_condition.operator === "in_range") {
          return String(row.match_condition.value || "-");
        }
      }
      return "-";
    },
    showOverflowTooltip: true,
  },
  {
    label: "状态",
    prop: "is_enabled",
    minWidth: 100,
    align: "center",
    slot: "status",
  },
  {
    label: "创建人",
    prop: "created_by",
    minWidth: 100,
  },
  {
    label: "创建时间",
    prop: "created_at",
    minWidth: 160,
  },
  {
    label: "操作",
    prop: "action",
    minWidth: 150,
    fixed: "right",
    slot: "action",
  },
];

// 获取规则类型名称
const getRuleTypeName = (type?: string): string => {
  const typeMap: Record<string, string> = {
    ip: "IP地址",
    ip_range: "IP段",
    port: "端口",
    cve: "CVE",
    dimension: "维度",
    custom: "自定义",
  };
  return typeMap[type || ""] || type || "-";
};

// 获取列表数据
const fetchList = async () => {
  loading.value = true;
  try {
    const params: any = {
      page: pagination.currentPage,
      page_size: pagination.pageSize,
      sort_by: "created_at",
      sort_order: "desc",
    };

    if (formData.rule_type) params.rule_type = formData.rule_type;
    if (formData.is_enabled !== "") {
      params.is_enabled = formData.is_enabled === "true";
    }
    if (formData.keyword) params.keyword = formData.keyword;

    const { data } = await getWhitelistRuleList(params);

    tableData.value = (data.items || []).map((item: any) => ({
      ...item,
      _switching: false,
    }));
    pagination.total = data.total || 0;
  } catch (error: any) {
    console.error("获取列表失败:", error);
    ElMessage.error(error.message || "获取列表失败");
  } finally {
    loading.value = false;
  }
};

// 搜索
const handleSearch = () => {
  pagination.currentPage = 1;
  fetchList();
};

// 重置
const handleReset = () => {
  formData.rule_type = "";
  formData.is_enabled = "";
  formData.keyword = "";
  pagination.currentPage = 1;
  fetchList();
};

// 分页变化
const handleSizeChange = (size: number) => {
  pagination.pageSize = size;
  pagination.currentPage = 1;
  fetchList();
};

const handlePageChange = (page: number) => {
  pagination.currentPage = page;
  fetchList();
};

// 选择变化
const handleSelectionChange = (rows: any[]) => {
  selectedRows.value = rows;
};

// 状态切换
const handleStatusChange = async (row: any) => {
  if (row._switching) return;

  row._switching = true;
  try {
    await updateWhitelistRule({
      id: row.id,
      is_enabled: row.is_enabled,
    });

    ElMessage.success(row.is_enabled ? "启用成功" : "禁用成功");
    fetchList();
  } catch (error: any) {
    // 回滚状态
    row.is_enabled = !row.is_enabled;
    ElMessage.error(error.message || "操作失败");
  } finally {
    row._switching = false;
  }
};

// 创建规则
const handleCreate = () => {
  isEdit.value = false;
  currentRuleId.value = null;
  resetRuleForm();
  showDialog.value = true;
};

// 编辑规则
const handleEdit = (row: any) => {
  isEdit.value = true;
  currentRuleId.value = row.id;

  // 填充表单数据
  ruleFormData.rule_name = row.rule_name || "";
  ruleFormData.rule_type = row.rule_type || "ip_range";
  ruleFormData.rule_description = row.rule_description || "";
  ruleFormData.applicable_dimensions = row.applicable_dimensions || [];
  ruleFormData.is_enabled =
    row.is_enabled !== undefined ? row.is_enabled : true;

  // 处理匹配条件
  if (row.match_condition) {
    if (row.rule_type === "ip_range") {
      if (
        row.match_condition.value &&
        row.match_condition.value.includes("/")
      ) {
        ruleFormData.match_condition_cidr = row.match_condition.value;
      } else {
        // 处理IP范围
        const parts = String(row.match_condition.value).split("-");
        if (parts.length === 2) {
          ruleFormData.match_condition_start_ip = parts[0].trim();
          ruleFormData.match_condition_end_ip = parts[1].trim();
        }
      }
    } else {
      ruleFormData.match_condition_value = String(
        row.match_condition.value || ""
      );
    }
  }

  // 处理生效时间
  if (row.effective_start && row.effective_end) {
    ruleFormData.effective_time_type = "time_range";
    ruleFormData.effective_start = row.effective_start;
    ruleFormData.effective_end = row.effective_end;
  } else {
    ruleFormData.effective_time_type = "permanent";
    ruleFormData.effective_start = "";
    ruleFormData.effective_end = "";
  }

  showDialog.value = true;
};

// 删除规则
const handleDelete = async (row: any) => {
  try {
    await ElMessageBox.confirm(
      `确定要删除规则"${row.rule_name}"吗？删除后无法恢复。`,
      "删除确认",
      {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      }
    );

    await deleteWhitelistRule({ id: row.id });

    ElMessage.success("删除成功");
    fetchList();
  } catch (error: any) {
    if (error !== "cancel") {
      ElMessage.error(error.message || "删除失败");
    }
  }
};

// 保存规则
const handleSave = async (values: any) => {
  // 表单验证
  if (!ruleFormRef.value) {
    ElMessage.error("表单引用不存在");
    return;
  }

  try {
    await ruleFormRef.value.validate();
  } catch (error) {
    ElMessage.warning("请完善表单信息");
    return;
  }

  try {
    // 构建匹配条件
    let matchCondition: any = {
      field: "asset_ip",
      operator: "equals",
      value: "",
    };

    ruleFormData.rule_type = values.rule_type;
    ruleFormData.match_condition_value = values.match_condition_value;
    ruleFormData.match_condition_cidr = values.match_condition_cidr;
    ruleFormData.match_condition_start_ip = values.match_condition_start_ip;
    ruleFormData.match_condition_end_ip = values.match_condition_end_ip;
    ruleFormData.applicable_dimensions = values.applicable_dimensions;
    ruleFormData.effective_time_type = values.effective_time_type;
    ruleFormData.effective_start = values.effective_start;
    ruleFormData.effective_end = values.effective_end;
    ruleFormData.is_enabled = values.is_enabled;
    ruleFormData.rule_name = values.rule_name;
    ruleFormData.rule_description = values.rule_description;

    if (ruleFormData.rule_type === "ip_range") {
      if (ruleFormData.match_condition_cidr) {
        matchCondition = {
          field: "asset_ip",
          operator: "in_range",
          value: ruleFormData.match_condition_cidr,
        };
      } else if (
        ruleFormData.match_condition_start_ip &&
        ruleFormData.match_condition_end_ip
      ) {
        matchCondition = {
          field: "asset_ip",
          operator: "in_range",
          value: `${ruleFormData.match_condition_start_ip}-${ruleFormData.match_condition_end_ip}`,
        };
      } else {
        ElMessage.warning("请填写CIDR或起始IP和结束IP");
        return;
      }
    } else if (ruleFormData.rule_type === "ip") {
      if (!ruleFormData.match_condition_value) {
        ElMessage.warning("请输入IP地址");
        return;
      }
      matchCondition = {
        field: "asset_ip",
        operator: "equals",
        value: ruleFormData.match_condition_value,
      };
    } else if (ruleFormData.rule_type === "port") {
      if (!ruleFormData.match_condition_value) {
        ElMessage.warning("请输入端口号");
        return;
      }
      const ports = ruleFormData.match_condition_value
        .split(",")
        .map((p) => p.trim())
        .filter((p) => p);
      if (ports.length === 0) {
        ElMessage.warning("请输入有效的端口号");
        return;
      }
      matchCondition = {
        field: "port",
        operator: ports.length === 1 ? "equals" : "in",
        value: ports.length === 1 ? ports[0] : ports,
      };
    } else if (ruleFormData.rule_type === "cve") {
      if (!ruleFormData.match_condition_value) {
        ElMessage.warning("请输入CVE编号");
        return;
      }
      matchCondition = {
        field: "cve_id",
        operator: "equals",
        value: ruleFormData.match_condition_value,
      };
    } else {
      if (!ruleFormData.match_condition_value) {
        ElMessage.warning("请输入匹配值");
        return;
      }
      matchCondition = {
        field: "custom",
        operator: "equals",
        value: ruleFormData.match_condition_value,
      };
    }

    const ruleData: any = {
      rule_name: ruleFormData.rule_name,
      rule_type: ruleFormData.rule_type,
      rule_description: ruleFormData.rule_description,
      match_condition: matchCondition,
      applicable_dimensions: ruleFormData.applicable_dimensions,
      is_enabled: ruleFormData.is_enabled,
    };

    if (ruleFormData.effective_time_type === "time_range") {
      if (!ruleFormData.effective_start || !ruleFormData.effective_end) {
        ElMessage.warning("请选择生效时间范围");
        return;
      }
      ruleData.effective_start = ruleFormData.effective_start;
      ruleData.effective_end = ruleFormData.effective_end;
    } else {
      ruleData.effective_start = null;
      ruleData.effective_end = null;
    }

    let response;
    if (isEdit.value && currentRuleId.value) {
      response = await updateWhitelistRule({
        id: currentRuleId.value,
        ...ruleData,
      });
    } else {
      response = await createWhitelistRule(ruleData);
    }

    ElMessage.success(isEdit.value ? "更新成功" : "创建成功");
    showDialog.value = false;
    fetchList();
  } catch (error: any) {
    console.error("保存失败:", error);
    ElMessage.error(error.message || "保存失败");
  }
};

// 重置规则表单
const resetRuleForm = () => {
  ruleFormData.rule_name = "";
  ruleFormData.rule_type = "ip_range";
  ruleFormData.rule_description = "";
  ruleFormData.match_condition_field = "asset_ip";
  ruleFormData.match_condition_operator = "in_range";
  ruleFormData.match_condition_value = "";
  ruleFormData.match_condition_start_ip = "";
  ruleFormData.match_condition_end_ip = "";
  ruleFormData.match_condition_cidr = "";
  ruleFormData.applicable_dimensions = [];
  ruleFormData.effective_time_type = "permanent";
  ruleFormData.effective_start = "";
  ruleFormData.effective_end = "";
  ruleFormData.is_enabled = true;
};

// 关闭对话框
const handleCloseDialog = () => {
  showDialog.value = false;
  resetRuleForm();
};

// 初始化
onMounted(() => {
  fetchDimensionList();
  fetchList();
});
</script>

<style scoped lang="scss">
.whitelist-management {
  .filter-card {
    margin-bottom: 20px;
    border-radius: 8px;
    border: 1px solid #f0f0f0;
  }

  .table-card {
    border-radius: 8px;
    border: 1px solid #f0f0f0;
  }
}

::v-deep .el-form-item {
  margin-bottom: 10px;
}
</style>
